package com.zytlifeservice.service.pay;

import com.qianmi.open.api.ApiException;
import com.qianmi.open.api.request.BmRechargeMobileGetItemInfoRequest;
import com.qianmi.open.api.request.BmRechargeMobileGetPhoneInfoRequest;
import com.qianmi.open.api.request.BmRechargeMobilePayBillRequest;
import com.qianmi.open.api.response.BmRechargeMobileGetItemInfoResponse;
import com.qianmi.open.api.response.BmRechargeMobileGetPhoneInfoResponse;
import com.qianmi.open.api.response.BmRechargeMobilePayBillResponse;
import com.zytlifeservice.domain.Result;
import com.zytlifeservice.domain.User;
import com.zytlifeservice.domain.pay.*;
import com.zytlifeservice.exception.UserException;
import com.zytlifeservice.repository.UserRepository;
import com.zytlifeservice.repository.pay.AlipayOrderRepository;
import com.zytlifeservice.repository.pay.MobileRechargeOrderRepository;
import com.zytlifeservice.repository.pay.WxPayOrderRepository;
import com.zytlifeservice.util.ResultUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by MJS on 2017/5/26.
 */

@Service
public class MobileRechargeService {

    private static final Logger logger = LoggerFactory.getLogger(MobileRechargeService.class);
    @Autowired
    AlipayOrderRepository alipayOrderRepository;

    @Autowired
    WxPayOrderRepository wxPayOrderRepository;

    @Autowired
    MobileRechargeOrderRepository mobileRechargeOrderRepository;

    @Autowired
    MoblieAndFlowCostService moblieAndFlowCostService;

    @Autowired
    AlipayService alipayService;

    @Autowired
    WxPayService wxPayService;

    @Autowired
    PublicService publicService;

    @Autowired
    UserRepository userRepository;

    public String[] createOrder(String mobileNo, String rechargeAmount, Long userId) throws ApiException {
        User one = userRepository.findOne(userId);
        if (one == null) {
            throw new UserException("用户不存在", 104);
        }
        String[] res = new String[2];
        BmRechargeMobileGetItemInfoRequest req = new BmRechargeMobileGetItemInfoRequest();
        req.setMobileNo(mobileNo);
        req.setRechargeAmount(rechargeAmount);
        BmRechargeMobileGetItemInfoResponse response = publicService.execute(req);
        if (!response.isSuccess()) {
            res[0] = "fail";
            res[1] = response.getSubMsg();
            return res;
        }
        response.getMobileItemInfo().getItemName();  //是否需要自己处理商品信息？
        AlipayOrder alipayOrder = new AlipayOrder();
        alipayOrder.setStoreId(one.getStoreId());
        alipayOrder.setSubject(response.getMobileItemInfo().getItemName());//对应的后台的信息
        String outTradeNo = "zyt" + userId + System.currentTimeMillis()   //添加userId
                + (long) (Math.random() * 10000000L);
        alipayOrder.setOutTradeNo(outTradeNo);
        alipayOrder.setTotalAmount(rechargeAmount);
        alipayOrder.setUserId(userId);
        alipayOrder.setType(AlipayOrder.TYPE_MOBILE_RECHARGE);
        alipayOrder.setOrderStatus(AlipayOrder.ORDER_WAIT);
        alipayOrderRepository.save(alipayOrder);


        //同时，这里要生成千米的订单
        MobileRechargeOrder phoneChargeOrder = new MobileRechargeOrder();
        phoneChargeOrder.setPayType(BaseQmOrder.PAY_TYPE_ALIPAY);
        phoneChargeOrder.setRechargeAccount(mobileNo);
        phoneChargeOrder.setOperator(response.getMobileItemInfo().getOperator());
        phoneChargeOrder.setItemId(response.getMobileItemInfo().getItemId());
        phoneChargeOrder.setOutTradeNo(outTradeNo);
        phoneChargeOrder.setItemName(response.getMobileItemInfo().getItemName());
        phoneChargeOrder.setUserId(userId);
        phoneChargeOrder.setSaleAmount(response.getMobileItemInfo().getAdvicePrice());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        phoneChargeOrder.setOrderTime(sdf.format(new Date()));
        phoneChargeOrder.setPayState("0");  //这里修改其状态。
        phoneChargeOrder.setPayResult(BaseQmOrder.STATUS_INIT);
        if (!publicService.querySum(rechargeAmount)) {
            phoneChargeOrder.setFailReason("直销商余额不足,取消支付宝预下单");
            mobileRechargeOrderRepository.save(phoneChargeOrder);
            res[0] = "fail";
            res[1] = "直销商余额不足,取消支付宝预下单";
            return res;
        }
        publicService.setBaseOrderType(phoneChargeOrder);
        mobileRechargeOrderRepository.save(phoneChargeOrder);
        //这里还是要重新加一成判断，判断是否下单成功。
        String pay = alipayService.pay(alipayOrder);
        if (pay.equals("fail") || "exception".equals(pay)) {
            res[0] = "fail";
            res[1] = "支付宝下单失败";
            return res;
        }
        res[0] = "success";
        res[1] = pay + "," + outTradeNo;
        publicService.addScore(phoneChargeOrder);
        return res;
    }

    //执行微信支付流程
    public String[] createWxOrder(String mobileNo, String rechargeAmount, Long userId, String ip) throws ApiException {
        User one = userRepository.findOne(userId);
        if (one == null) {
            throw new UserException("用户不存在", 104);
        }
        String[] res = new String[2];
        BmRechargeMobileGetItemInfoRequest req = new BmRechargeMobileGetItemInfoRequest();
        req.setMobileNo(mobileNo);
        req.setRechargeAmount(rechargeAmount);
        BmRechargeMobileGetItemInfoResponse response = publicService.execute(req);
        if (!response.isSuccess()) {
            res[0] = "fail";
            res[1] = response.getMsg();
            return res;
        }
        String outTradeNo = "zyt" + userId + System.currentTimeMillis()   //添加userId
                + (long) (Math.random() * 10000000L);
        WxPayOrder wxPayOrder = publicService.generateWxpayOrder(one, response.getMobileItemInfo().getItemName(), ip,
                rechargeAmount, outTradeNo, WxPayOrder.TYPE_MOBILE_RECHARGE);
        wxPayOrderRepository.save(wxPayOrder);

        MobileRechargeOrder phoneChargeOrder = new MobileRechargeOrder();
        phoneChargeOrder.setPayType(BaseQmOrder.PAY_TYPE_WXPAY);
        phoneChargeOrder.setRechargeAccount(mobileNo);
        phoneChargeOrder.setOperator(response.getMobileItemInfo().getOperator());
        phoneChargeOrder.setItemId(response.getMobileItemInfo().getItemId());
        phoneChargeOrder.setOutTradeNo(outTradeNo);
        phoneChargeOrder.setItemName(response.getMobileItemInfo().getItemName());
        phoneChargeOrder.setUserId(userId);
        phoneChargeOrder.setSaleAmount(response.getMobileItemInfo().getAdvicePrice());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        phoneChargeOrder.setOrderTime(sdf.format(new Date()));
        phoneChargeOrder.setPayState("0");  //这里修改其状态。
        phoneChargeOrder.setPayResult(BaseQmOrder.STATUS_WAIT);
        if (!publicService.querySum(rechargeAmount)) {
            phoneChargeOrder.setFailReason("直销商余额不足,取消支付宝预下单");
            mobileRechargeOrderRepository.save(phoneChargeOrder);
            res[0] = "fail";
            res[1] = "直销商余额不足,取消支付宝预下单";
            return res;
        }
        publicService.setBaseOrderType(phoneChargeOrder);
        mobileRechargeOrderRepository.save(phoneChargeOrder);
        String pay = wxPayService.pay(wxPayOrder);
        if ("error".equals(pay)) {
            res[0] = "fail";
            res[1] = "微信下单失败";
            return res;
        }
        res[0] = "success";
        res[1] = pay + "," + outTradeNo;
        return res;
    }


    //这里要得到千米的订单信息。执行消费。
    public String payPhoneChargeOrder(String outTradeNo) throws ApiException {
        MobileRechargeOrder phoneChargeOrder = mobileRechargeOrderRepository.findByOutTradeNo(outTradeNo);
        logger.error("查询的order:{}", phoneChargeOrder);
        BmRechargeMobilePayBillRequest req = new BmRechargeMobilePayBillRequest();
        req.setMobileNo(phoneChargeOrder.getRechargeAccount());
        req.setRechargeAmount(phoneChargeOrder.getSaleAmount());
        req.setOuterTid(phoneChargeOrder.getOutTradeNo());
        req.setCallback(publicService.getBmCallbackUrl());
        BmRechargeMobilePayBillResponse response = publicService.execute(req);

        logger.error("支付状态:{}", response.isSuccess());
        logger.error("支付结果body:{}", response.getBody());
        if (!response.isSuccess()) {
            //处理错误
            //记录错误原因，同时，执行支付宝退款流程。
            phoneChargeOrder.setFailReason(response.getSubMsg());
            phoneChargeOrder.setPayResult(BaseQmOrder.STATUS_FAIL);
            mobileRechargeOrderRepository.save(phoneChargeOrder);
            //这里判断是由微信还是由支付宝执行退款。
            if (phoneChargeOrder.getPayType() == BaseQmOrder.PAY_TYPE_ALIPAY) {
                AlipayOrder byOutTradeNo = alipayOrderRepository.findByOutTradeNo(outTradeNo);
                byOutTradeNo.setRefundReason(response.getSubMsg());
                return alipayService.reFund(byOutTradeNo);
            } else if (phoneChargeOrder.getPayType() == BaseQmOrder.PAY_TYPE_WXPAY) {
                WxPayOrder wxPayOrder = wxPayOrderRepository.findByOutTradeNo(outTradeNo);
                wxPayOrder.setRefundReason(response.getSubMsg());
                return wxPayService.refund(wxPayOrder);
            }
        }
        //付款成功，解析结果，执行增加的消费操作。
        publicService.parseResponse(phoneChargeOrder, response.getOrderDetailInfo());
        mobileRechargeOrderRepository.save(phoneChargeOrder);
        return "error";
    }

    //查询手机账户详情
    public Result searchPhoneNo(String mobile) throws Exception {
        System.out.println("进入手机账户查询");
        BmRechargeMobileGetPhoneInfoRequest req = new BmRechargeMobileGetPhoneInfoRequest();
        req.setPhoneNo(mobile);
        req.setRespType("all");
        BmRechargeMobileGetPhoneInfoResponse response = publicService.execute(req);
        Map phoneMap = new HashMap();
        if (null != response.getPhoneInfo()) {
            phoneMap.put("province", response.getPhoneInfo().getProvince());
            phoneMap.put("city", response.getPhoneInfo().getCity());
            phoneMap.put("operator", response.getPhoneInfo().getOperator());
            phoneMap.put("phoneNo", response.getPhoneInfo().getPhoneNo());
            phoneMap.put("detail", response.getPhoneInfo().getDetail());
            return ResultUtil.success(phoneMap, "成功");
        } else {
            return ResultUtil.error(-1, "手机账户不存在");
        }
    }

    public List<MoblieAndFlowCost> queryAll() {
        return moblieAndFlowCostService.findAll();
    }
}
